﻿#define _CRT_SECURE_NO_WARNINGS
#include <cassert>
#include <cstring>
#include <iostream>
#include <vector>
#include <map>
using namespace std;

#include "string.h"

//学习C++11所用代码

//一:列表初始化
//struct Point
//{
//	int _x;
//	int _y;
//};
//class Date
//{
//	int _y;
//	int _m;
//	int _d;
//public:
//	Date(int y = 2025, int m = 6, int d = 3)
//		:_y(y)
//		, _m(m)
//		, _d(d)
//	{
//		cout << "Date(int y, int m, int d)" << endl;
//	}
//	Date(const Date& d)
//		:_y(d._y)
//		, _m(d._m)
//		, _d(d._d)
//	{
//		cout << "Date(const Date& d)" << endl;
//	}
//};
//int main()
//{
//	//C++98支持
//	int array[] = { 1, 2, 3, 4 };
//	struct Point p = { 1, 2 };
//
//	//C++11支持
//	
//	//内置类型
//	int x1 = { 1 };
//	int x2{ 2 };
//
//	//自定义类型
//	
//	//本质是构造+拷贝构造，编译器优化成直接构造初始化
//	Date d1 = { 2023, 12, 12 };
//	Date d2{ 2024, 12, 12 };
//	Date d3({ 2000 });
//
//	//这里d4引用的是{2024， 7， 5}构造的临时对象
//	const Date& d4 = { 2024, 7, 5 };
//	const Date& d5{ 2024, 7, 5 };
//
//	//需要注意的是C++98⽀持单参数时类型转换，也可以不⽤{}
//	Date d6 = { 2029 };
//	Date d7 = 2029;
//
//	//比起有名对象和匿名对象传参，这里{}更有性价比
//	vector<Date> v;
//	v.push_back(d6);
//	v.push_back(Date(2012, 12, 12));
//	v.push_back({ 2022, 10, 10 });
//	return 0;
//}

//二:初始化列表(initializer_list)
//int main()
//{
//	//initializer_list构造直接构造
//	vector<int> v1({ 1, 2, 3, 4 });
//	//语义上:构造initializer_list临时对象+拷贝构造，优化为直接构造
//	vector<int> v2 = { 1, 2, 3 };
//	//pair对象的{}初始化和map的initializer_list构造结合
//	map<string, string> dict = { {"haha", "哈哈"}, {"totoro", "龙猫"} };
//	//initializer_list版本的赋值支持
//	v1 = { 1, 2 };
//	return 0;
//}

//左值引用和右值引用
//int main()
//{
//	//左值引用不能直接引用右值，但是const左值可以引用右值
//	const int& a = 1;
//	//右值引用不能直接引用左值，但是右值引用可以引用move(左值)
//	int tmp = 1;
//	int&& b = move(tmp);
//
//	//右值引用本身属性是左值
//	int& c = b;
//	//int&& d = b;//右值引用不能直接引用左值
//
//	//在当前作用域内，右值引用可以延长临时对象生命周期
//	string s1 = "hello", s2 = " world";
//	string&& s3 = s1 + s2;//s1+s2产生临时对象
//	//可以通过非const的引用修改
//	s3 = "xixi";
//	cout << s3 << endl;
//
//	//const的左值引用也可以延长临时对象生命周期，但是这些临时对象无法被修改
//	const string& s4 = s1 + s2;
//	//s4 = "xixi";//无法修改
//	cout << s4 << endl;
//	return 0;
//}


//右值引用和移动语义
// 传值返回需要拷⻉ 
//HD::string addStrings(HD::string num1, HD::string num2) {
//	HD::string str;
//	int end1 = num1.size() - 1, end2 = num2.size() - 1;
//	// 进位 
//	int next = 0;
//	while (end1 >= 0 || end2 >= 0)
//	{
//		int val1 = end1 >= 0 ? num1[end1--] - '0' : 0;
//		int val2 = end2 >= 0 ? num2[end2--] - '0' : 0;
//		int ret = val1 + val2 + next;
//		next = ret / 10;
//		ret = ret % 10;
//		str += ('0' + ret);
//	}
//	if (next == 1)
//		str += '1';
//	reverse(str.begin(), str.end());
//	return str;
//}
//int main()
//{
//	HD::string s1;
//	s1 = addStrings("11", "22");
//	cout << s1 << endl;
//	return 0;
//}

//引用折叠
//template <class T>
//void Func(T&& tmp)
//{
//	T x = tmp;
//	//x++;
//	cout << &x << endl;
//	cout << &tmp << endl;
//}
//int main()
//{
//	//传入右值，T被识别成int，函数模板被实例化为
//	//void Func(int&& tmp)
//	//Func(1);
//
//	//传入左值，T被识别成int&，由于引用折叠，函数模板被实例化为
//	//void Func(int& tmp)
//	int a = 1;
//	//Func(a);
//
//	//传入右值，T被识别成为int，函数模板被实例化为
//	//void Func(int&& tmp)
//	Func(move(a));
//
//	//传入右值，T被识别成const int, 函数模板被实例化为
//	//void Func(const int&& tmp)。所以x不能++
//	const int b = 1;
//	//Func(move(b));
//
//	//传入左值，T被识别成const int&，由于引用折叠，函数模板被实例化为
//	//void Func(const int& tmp)。所以x不能++
//	//Func(b);
//	return 0;
//}

//完美转发
void Print(int& t)
{
	cout << "左值引用" << endl;
}
void Print(const int& t)
{
	cout << "const左值引用" << endl;
}
void Print(int&& t)
{
	cout << "右值引用" << endl;
}
void Print(const int&& t)
{
	cout << "const右值引用" << endl;
}
template <class T>
void Func(T&& tmp)
{
	Print(forward<T>(tmp));
}
int main()
{
	int a = 1;
	const int b = 1;
	Func(a);//左值
	Func(b);//const左值
	Func(1);//右值
	Func(move(b));//const右值
	return 0;
}